package Project1;

import java.io.Serializable;
import java.sql.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

@Entity
@Table(name="dept_emp")
public class DepartmentEmp implements Serializable {
	private long emp_no;
	private String dept_no;
	private Date from_date;
	private Date to_date;
	private Employee employee;
	private Department department;
	

	public DepartmentEmp(){}
	
	public DepartmentEmp(long emp_no, String dept_no, Date from_date,
			Date to_date, Employee employee, Department department) {
		super();
		this.emp_no = emp_no;
		this.dept_no = dept_no;
		this.from_date = from_date;
		this.to_date = to_date;
		this.employee = employee;
		this.department = department;
	}
//***********************GETTERS AND SETTERS*****************************************
	@Id
	@Column(name="emp_no")
	public long getEmp_no() {return emp_no;}
	public void setEmp_no(long emp_no) {this.emp_no = emp_no;}

	@Id
	@Column(name="dept_no")
	public String getDept_no() {return dept_no;}
	public void setDept_no(String dept_no) {this.dept_no = dept_no;}

	@Column(name="from_date")
	public Date getFrom_date() {return from_date;}
	public void setFrom_date(Date from_date) {this.from_date = from_date;}

	@Column(name="to_date")
	public Date getTo_date() {return to_date;}
	public void setTo_date(Date to_date) {this.to_date = to_date;}

	@ManyToOne
	@JoinColumn(name="emp_no")
	public Employee getEmployee() {return employee;}
	public void setEmployee(Employee employee) {this.employee = employee;}

	@ManyToOne
	@JoinColumn(name="dept_no")
	public Department getDepartment() {return department;}
	public void setDepartment(Department department) {this.department = department;}
	//**************************METHODS********************************
	public void print(){
		System.out.printf("%d, %s: from %s to %s\n", emp_no, dept_no, from_date.toString(), to_date.toString());
	}

	//*****************STATIC METHODS***************************************
	/**
	 * Lists all Department Employees in database
	 */
	public static void list(){
		
		Session session = HibernateContext.getSession();
		Criteria criteria = session.createCriteria(DepartmentEmp.class);
		criteria.addOrder(Order.asc("emp_no"));
		
		List<DepartmentEmp> emps = criteria.list();
		System.out.println("All Department Employees:");
		
		for(DepartmentEmp e : emps){
			e.print();
		}
		session.close();
	}
	/**
	 * Gets department Employee by employee number and department number
	 * @param emp_no
	 * @param dept_no
	 * @return
	 */
	public static DepartmentEmp find(long emp_no, String dept_no){
    	// Query using HQL.
        Session session = HibernateContext.getSession();
        Query query = session.createQuery("from DepartmentEmp where emp_no = :idvar and dept_no = :deptvar");
        query.setLong("idvar", emp_no);
        query.setString("deptvar", dept_no);
        DepartmentEmp d = (DepartmentEmp) query.uniqueResult();
       
        session.close();
        return d;
	}
	/**
	 * Prints names of all employees of a department
	 * @param dept_name
	 */
	public static void employeesOf(String dept_name){
		Session sess = HibernateContext.getSession();
		Criteria empCrit = sess.createCriteria(Employee.class);
		Criteria deptCrit = empCrit.createCriteria("department_emp");
		Criteria depart = deptCrit.createCriteria("department");
		
		depart.add(Restrictions.eq("dept_name", dept_name));
		
		empCrit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		empCrit.addOrder(Order.asc("emp_no"));
		
		List<Employee> emps = (List<Employee>) empCrit.list();
		System.out.println("Employees in " + dept_name + " department");
		for(Employee e: emps){
			System.out.printf("\t %s %s\n", e.getFirst_name(), e.getLast_name());
		}
	}
	
	
}
